package sg.edu.nus.iss.vmcs.system;

import java.io.*;

import sg.edu.nus.iss.vmcs.command.StoreCashCmd;
import sg.edu.nus.iss.vmcs.customer.*;
import sg.edu.nus.iss.vmcs.maintenance.*;
import sg.edu.nus.iss.vmcs.machinery.*;
import sg.edu.nus.iss.vmcs.store.*;
import sg.edu.nus.iss.vmcs.util.*;

/**
 * 
 * @version 1.1
 * @author Chen Wei, Qu Hui
 * 
 */
public class MainController {

	private SimulationController simulatorCtrl;
	private TransactionController transactionCtrl;
	private CoinReceiver coinReceiver;
	private MachineryController machineryCtrl;
	private MaintenanceController maintenanceCtrl;
	private StoreController storeCtrl;

	private String propertyFile;

	public MainController(String propertyFile) {
		this.propertyFile = propertyFile;
	}

	public void start() throws VMCSException {
		try {
			initialize();
			simulatorCtrl.displaySimulatorControlPanel();
			simulatorCtrl.setSimulationActive(false);
		} catch (VMCSException e) {
			throw new VMCSException(e);
		}
	}

	public void initialize() throws VMCSException {
		try {
			Environment.initialize(propertyFile);
			// modified by chen wei
			/*
			 * CashPropertyLoader cashLoader = new
			 * CashPropertyLoader(Environment.getCashPropFile());
			 * DrinkPropertyLoader drinksLoader = new
			 * DrinkPropertyLoader(Environment.getDrinkPropFile()); storeCtrl =
			 * new StoreController(cashLoader, drinksLoader);
			 */

			// here can implement factory to instantiate suitable PropertyImp
			PropertyImp cashPropImp = new FilePropertyImp(
					Environment.getCashPropFile());
			PropertyImp drinkPropImp = new FilePropertyImp(
					Environment.getDrinkPropFile());
			CashLoader cashLoader = new CashLoader(cashPropImp);
			DrinkLoader drinksLoader = new DrinkLoader(drinkPropImp);
			cashPropImp.init();
			drinkPropImp.init();

			storeCtrl = new StoreController(cashLoader, drinksLoader,
					cashPropImp, drinkPropImp);
			// end of modified by chen wei
			storeCtrl.initialize();
			simulatorCtrl = new SimulationController(this);
			transactionCtrl = new TransactionController(this);
			// initializeCommand();
			machineryCtrl = new MachineryController(this);
			machineryCtrl.initialize();
			maintenanceCtrl = new MaintenanceController(this);
		} catch (IOException e) {
			throw new VMCSException("MainController.initialize", e.getMessage());
			// added by chen wei
		} catch (PropertyException e) {
			throw new VMCSException("MainController.initialize", e.getMessage());
		}
		// end of added by chen wei

	}

	private void initializeCommand() {
		coinReceiver = new CoinReceiver(transactionCtrl);
		StoreCashCmd storeCashCmd = new StoreCashCmd(coinReceiver);
		transactionCtrl.addCommand("ReceiveCoin", storeCashCmd);
	}

	public SimulationController getSimulationController() {
		return simulatorCtrl;
	}

	public SimulatorControlPanel getSimulatorControlPanel() {
		return simulatorCtrl.getSimulatorControlPanel();
	}

	public StoreController getStoreController() {
		return storeCtrl;
	}

	public TransactionController getTransactionController() {
		return transactionCtrl;
	}

	public MachineryController getMachineryController() {
		return machineryCtrl;
	}

	public MaintenanceController getMaintenanceController() {
		return maintenanceCtrl;
	}

	public void closeDown() {
		try {
			storeCtrl.closeDown();
		} catch (Exception e) {
			System.out.println("Error closing down the stores: " + e);
		}
		transactionCtrl.closeDown();
		machineryCtrl.closeDown();
		maintenanceCtrl.closeDown();
		simulatorCtrl.closeDown();
	}
}
